package com.easytoolsoft.easyreport.web.controllers;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
//import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;
import org.omg.CORBA.ARG_IN;
/*import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;*/
/*import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.util.EntityUtils;*/
/*import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;*/
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.apache.http.client.methods.HttpGet;
import com.alibaba.fastjson.JSON;
/*import com.sg.common.empty.aop.CustomerAop;
import com.sg.common.empty.core.DealFilter;
import com.sg.common.empty.core.DealPermission;
import com.sg.common.empty.core.EpUtil;
import com.sg.common.empty.service.CfgService;
import com.sg.common.login.entity.Member;
import com.sg.common.login.entity.Org;
import com.sg.common.login.entity.Role;
import com.sg.common.login.service.OrgMemberService;
import com.sg.common.utils.Constant;
import com.sg.common.utils.StrUtil;*/
import com.alibaba.fastjson.JSONObject;
/*import com.sg.common.http.HttpHelper;
import com.sg.common.utils.Constant;*/
/*import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;*/
/*import com.sg.common.empty.web.SessionUtil;
import com.sg.common.login.entity.Member;
*/
/*import com.sg.common.http.HttpHelper;
import com.sg.common.utils.Constant;*/
/*import com.sg.common.empty.web.SessionUtil;
import com.sg.common.utils.Constant;*/
//import com.sg.common.empty.service.CfgService;
import com.easytoolsoft.easyreport.engine.data.ReportDataSource;
import com.easytoolsoft.easyreport.po.DataSourcePo;


public class EmptyInterceptor implements HandlerInterceptor {
	QueryController service;
	private Logger logger = LoggerFactory.getLogger(getClass());

	private String[] allowUrls;

	/*
	 * @Autowired CfgService service;
	 * 
	 * @Autowired OrgMemberService omService;
	 */
	/**
	 * preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用，
	 * SpringMVC中的Interceptor拦截器是链式的，可以同时存在
	 * 多个Interceptor，然后SpringMVC会根据声明的前后顺序一个接一个的执行 ，而且所有的Interceptor中的preHandle方法都会在
	 * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的 ，这种中断方式是令preHandle的返
	 * 回值为false，当preHandle的返回值为false的时候整个请求就结束了。
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		String requestUrl = request.getRequestURI().replace(request.getContextPath(), "");
		// url检测
		if (urlFilter(requestUrl)) {
			return true;
		}
		logger.info(requestUrl + " " + request.getQueryString());
		System.out.println(requestUrl);
		int lastIndex = StringUtils.lastIndexOf(requestUrl, "/");
		String header = StringUtils.substring(requestUrl, 1, lastIndex).replace("/", ".");
		String route = header + "." + StringUtils.substring(requestUrl, lastIndex + 1);
		request.setAttribute("conf.header", header);
		request.setAttribute("conf.route", route);
		/**
		 * 通过获取工号判断是否已经登录， 如果已经登录，返回登录人工号，如果没有登录，返回为空，详见方法
		 */
		String memberCode = findMyCode(request);

		if (StringUtils.isEmpty(memberCode)) {
			// 没有登录的情况
			request.setAttribute("errMsg", "该功能Permission需要权限,但用户为空,返回");
			request.getRequestDispatcher("/login").forward(request, response);

			return true;
		} else {
			// 登录情况下
			List<String> roleCodes = findRemoteRoles(request, memberCode);

			if (RoleMatch(roleCodes, requestUrl)) {// 角色匹配
				// 获取登录人组织 方法一 Integer memberCode = findMyCode(request);
				// 获取登录人组织 方法二 直接连接主数据系统数据库进行查询，获取人员组织
				// 获取登录人的有效行政组织id
				//String OrgMemberId = findOrgmember(request, memberCode);

				HttpSession session = request.getSession();
				session.setAttribute(Constant.SESSION_MEMBER_CODE, memberCode);
				session.setAttribute(Constant.SESSION_MYROLES_CODE, roleCodes);
				// session.setAttribute(Constant.SESSION_MEMBER_ORG, OrgMemberId);
				// request.getSession().setAttribute(Constant.SESSION_MYROLES_CODE, roleCodes);

				return true;
			} else {
				// 角色不匹配
				Map<String, Object> res = new HashMap<String, Object>();
				res.put("code", 4030);
				res.put("msg", "没有找到对应的角色");
				response.setStatus(200);
				responseOutWithJson(response, res);
				return false;

			}

		}

	}

	/*
	 * private boolean delayerMatchurl(String requestUrl) { if
	 * (requestUrl.contains("report/uid/5e820117-8558-4d74-a03c-6890610fe9de")) {
	 * return true; }else { return false; } }
	 */

	private boolean RoleMatch(List<String> roleCodes, String requestUrl) {
		if (roleCodes == null || roleCodes.size() == 0) {
			return false;
		}

		if (roleCodes.contains("adminRPT")) {
			return true;
		}
		// String e[] = { "/report/uid/5e820117-8558-4d74-a03c-6890610fe9de",
		// "/report/uid/02983e99-34a7-40bd-a717-5439981f2c7d"};
		// 延误及晚点日报
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/5e820117-8558-4d74-a03c-6890610fe9de")) {
			return true;
		}
		// 5分钟断面客流
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/416cf7dd-66f6-4598-a512-0e9a9d5c6ba1")) {
			return true;
		}
		// 晚点情况分布表
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/855820ed-e41a-46e9-b422-843aab92968b")) {
			return true;
		}

		// 列车延误统计表http://10.10.39.1:8087/easyreport-web         /report/uid/9171bb9c-23fa-47de-8713-93a154dd50d3
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/9171bb9c-23fa-47de-8713-93a154dd50d3")) {
			return true;
		}
		
		
		
		
		
		// 线网运营概况表
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/42089c76-d297-48b1-ae3d-8b6e3956cd41")) {
			return true;
		}

		// 行车指标明细表
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/55cd2020-9938-4546-b108-929c435a2815")) {
			return true;
		}

		// 列车紧急制动原因表
		if (roleCodes.contains("delayerRPT") && requestUrl.equals("/report/uid/a2110b1a-4282-4581-a73f-247eba1b516c")) {
			return true;
		}
		
		
		
		//能源管理系统报表http:
		if (roleCodes.contains("nengyuanRPT") && requestUrl.equals("/report/uid/f67fc608-b18b-45cd-b0d6-00b7b1e5cf54")) {
			return true;
		}
		
		//能源管理系统报表
		if (roleCodes.contains("nengyuanRPT") && requestUrl.equals("/report/uid/88d2f924-e044-4697-8c79-dfd490784736")) {
				return true;
				}
		return false;

	}

	/*
	 * private static boolean ifMatch(String str1, String str2) {
	 * 
	 * 
	 * 
	 * 
	 * if(str1==null&str2==null){ return true; } if(str1==null&"".equals(str2)){
	 * return true; } if(str2==null&str1==null){ return true; }
	 * if(str2==null&"".equals(str1)){ return true; } return
	 * str1==null?str2.equals(str1):str1.equals(str2); }
	 * 
	 * 
	 * 
	 * 
	 */

	/**
	 * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的，
	 * 它的执行时间是在处理器进行处理之 后，也就是在Controller的方法调用之后执行，但是它会在DispatcherServlet进行视图的渲染之前执行
	 * ，也就是说在这个方法中你可以对ModelAndView进行操
	 * 作。这个方法的链式结构跟正常访问的方向是相反的，也就是说先声明的Interceptor拦截器该方法反而会后调用
	 * ，这跟Struts2里面的拦截器的执行过程有点像，
	 * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法
	 * ，Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor
	 * 或者是调用action，然后要在Interceptor之前调用的内容都写在调用invoke之前
	 * ，要在Interceptor之后调用的内容都写在调用invoke方法之后。
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		String requestUrl = request.getRequestURI().replace(request.getContextPath(), "");
		String afterClazz = Constant.get(requestUrl);
		if (StringUtils.isNotEmpty(afterClazz)) {
			Class<?> clazz = Class.forName(afterClazz);
			CustomerAop ca = (CustomerAop) clazz.newInstance();
			ca.setService(service);
			ca.post(request, response, handler, modelAndView);
		}
	}

	
	/*public static String findOrgmember(HttpServletRequest request, String memberCode) {
		 String OrgmemberId ="";
		Map<String, String> mip = new HashMap<String, String>();
		mip.put("memberCode", memberCode);
		JSONObject httpRes = httpPost(Constant.get("orgmember"), mip);
		if (httpRes != null && StringUtils.equals(httpRes.getString("errmsg"), "ok")) {
			OrgmemberId = httpRes.getString("OrgMemberId");			
		}
		return OrgmemberId;
	}*/
	
	
	
	
	
	
	
	
	
	
	
	
	
	public static List<String> findRemoteRoles(HttpServletRequest request, String memberCode) {
		List<String> roleCodes = new ArrayList<String>();
		Map<String, String> mip = new HashMap<String, String>();
		mip.put("code", memberCode);
		mip.put("sName", Constant.get("sName"));
		JSONObject httpRes = httpPost(Constant.get("remoteRoles"), mip);
		if (httpRes != null && StringUtils.equals(httpRes.getString("errmsg"), "ok")) {
			String roleCodesStr = httpRes.getString("roleCodes");
			if (StringUtils.isNotEmpty(roleCodesStr)) {
				String[] split = StringUtils.split(roleCodesStr, ":");
				roleCodes = java.util.Arrays.asList(split);
			}
		}
		return roleCodes;
	}

	public static String findMyCode(HttpServletRequest request) {
		String memberCode = "";
		String role = "";
		Map<String, String> mip = new HashMap<String, String>();
		mip.put("clientIp", request.getRemoteAddr());//request.getRemoteAddr()为本地的IP地址
		JSONObject httpRes = httpPost(Constant.get("checkin"), mip);//checkin:http://10.10.39.1:8082/auth/checkIn.sg      mip:{clientIp=10.10.156.175}
		
		/*
		 * JSONObject httpRes = httpPost("http://10.10.39.1:8082/auth/checkIn.sg", mip);
		 */

		if (httpRes != null && StringUtils.equals(httpRes.getString("errmsg"), "ok")) {
			memberCode = httpRes.getString("loginid");//将loginid转换为String类型

			// http://10.10.39.1:8082/auth/getRoles.sg?code=201571&sName=ISM

		}
		return memberCode;
	}

	public static JSONObject httpPost(String url, Object data) {
		//url=http://10.10.39.1:8082/auth/checkIn.sg;data:{clientIp=10.10.156.175}
		HttpPost httpPost = new HttpPost(url);
		//httpPost =POST http://10.10.39.1:8082/auth/checkIn.sg HTTP/1.1
		CloseableHttpResponse response = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		//httpClient =org.apache.http.impl.client.InternalHttpClient@10690e4f
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(2000).build();
		httpPost.setConfig(requestConfig);
		httpPost.addHeader("Content-Type", "application/json");
		//httpPost=POST http://10.10.39.1:8082/auth/checkIn.sg HTTP/1.1

		try {
			StringEntity requestEntity = new StringEntity(JSON.toJSONString(data), "utf-8");
			httpPost.setEntity(requestEntity);

			response = httpClient.execute(httpPost, new BasicHttpContext());
//response =HTTP/1.1 200 OK [Server: Apache-Coyote/1.1, Content-Type: application/json;charset=utf-8, Content-Length: 71, Date: Mon, 29 Jan 2018 08:51:13 GMT, Connection: close]
			if (response.getStatusLine().getStatusCode() != 200) {

				System.out.println("request url failed, http code=" + response.getStatusLine().getStatusCode() + ", url=" + url);

				return null;
			}
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String resultStr = EntityUtils.toString(entity, "utf-8");

				JSONObject result = JSON.parseObject(resultStr);
				if (result.getString("errmsg").equals("ok")) {
					return result;
				} else {
					System.out.println("request url=" + url + ",return value=");
					System.out.println(resultStr);
				}
			}
		} catch (IOException e) {
			System.out.println("request url=" + url + ", exception, msg=" + e.getMessage());
			e.printStackTrace();
		} finally {
			if (response != null)
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}

		return null;
	}

	/**
	 * 以JSON格式输出
	 * 
	 * @param response
	 */
	protected void responseOutWithJson(HttpServletResponse response, Object responseObject) {
		// 将实体对象转换为JSON Object转换
		String json = JSON.toJSONString(responseObject);
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.append(json);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

	private boolean urlFilter(String requestUrl) {

		if (null != getAllowUrls() && getAllowUrls().length >= 1) {
			for (String url : getAllowUrls()) {
				if (requestUrl.contains(url)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后，
	 * 也就是DispatcherServlet渲染了视图执行，
	 * 这个方法的主要作用是用于清理资源的，当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		if (ex == null) {
			String requestUrl = request.getRequestURI().replace(request.getContextPath(), "");
			String afterClazz = Constant.get(requestUrl);
			if (StringUtils.isNotEmpty(afterClazz)) {
				Class<?> clazz = Class.forName(afterClazz);
				CustomerAop ca = (CustomerAop) clazz.newInstance();
				ca.setService(service);
				ca.after(request, response, handler);
			}
		}
	}

	public String[] getAllowUrls() {
		return allowUrls;
	}

	public void setAllowUrls(String[] allowUrls) {
		this.allowUrls = allowUrls;
	}

}
